﻿using Mahjong.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace Mahjong.Method
{
    /// <summary>
    /// 玩家运算
    /// </summary>
    public class Player
    {
        public Player()
        {
            PlayerCards = new ObservableCollection<TypeModel>();
            PlayedCards = new ObservableCollection<TypeModel>();
            OpenedCardsUnKong = new ObservableCollection<TypeModel>();
            OpenedCardsKong = new ObservableCollection<TypeModel>();
            OpenedCardsPung = new ObservableCollection<TypeModel>();
            OpenedCardsChow = new ObservableCollection<TypeModel>();
            IsComputer = false;
        }

        #region 属性定义

        /// <summary>
        /// 玩家牌面
        /// </summary>
        public ObservableCollection<TypeModel> PlayerCards { get; }

        /// <summary>
        /// 玩家已打牌面
        /// </summary>
        public ObservableCollection<TypeModel> PlayedCards { get; }

        /// <summary>
        /// 玩家暗杠牌面
        /// </summary>
        public ObservableCollection<TypeModel> OpenedCardsUnKong { get; }

        /// <summary>
        /// 玩家明杠牌面
        /// </summary>
        public ObservableCollection<TypeModel> OpenedCardsKong { get; }

        /// <summary>
        /// 玩家碰牌面
        /// </summary>
        public ObservableCollection<TypeModel> OpenedCardsPung { get; }

        /// <summary>
        /// 玩家吃牌面
        /// </summary>
        public ObservableCollection<TypeModel> OpenedCardsChow { get; }

        /// <summary>
        /// 是否电脑玩家（1是，0否）
        /// </summary>
        public Boolean IsComputer { get; set; }

        #endregion 属性定义

        #region 普通方法

        /// <summary>
        /// 打牌
        /// </summary>
        /// <param name="SerialNumber">人工第几张</param>
        /// <returns>已打的牌</returns>
        public TypeModel Play(int SerialNumber)
        {
            TypeModel t;
            if (IsComputer == false)
            {
                if (SerialNumber != -1)
                {
                    t = new TypeModel(PlayerCards[SerialNumber]);
                    if (Application.Current != null)
                    {
                        Application.Current?.Dispatcher.Invoke((Action)(() => { PlayerCards.RemoveAt(SerialNumber); }));
                    }
                    return t;
                }
                else
                {
                    t = new TypeModel(PlayerCards.Last());
                    if (Application.Current != null)
                    {
                        Application.Current?.Dispatcher.Invoke((Action)(() => { PlayerCards.RemoveAt(PlayerCards.Count - 1); }));
                    }
                    return t;
                }
            }
            else
            {
                //需添加打牌判断
                Random random = new Random();
                int Index = random.Next(PlayerCards.Count);
                t = new TypeModel(PlayerCards[Index]);
                if (Application.Current != null)
                {
                    Application.Current?.Dispatcher.Invoke((Action)(() => { PlayerCards.RemoveAt(Index); }));
                }
                return t;
            }
            
        }

        /// <summary>
        /// 排序
        /// </summary>
        public void Sort()
        {
            List<TypeModel> lst = new List<TypeModel>(PlayerCards);
            lst.Sort(
                (x, y) =>
                {
                    var oSuit = x.Suit - y.Suit;

                    if (oSuit == 0)
                    {
                        if (x.Rank > y.Rank)
                        {
                            return 1;
                        }
                        else if (x.Rank == y.Rank)
                        {
                            return 0;
                        }
                        else
                        {
                            return -1;
                        }
                    }
                    else
                        return Convert.ToInt32(oSuit);
                }
            );
            for (int i = 0; i < lst.Count; i++)
            {
                PlayerCards[i] = lst[i];
            }
        }

        /// <summary>
        /// 入手待定牌
        /// </summary>
        /// <param name="t"></param>
        public void Commmence(TypeModel t)
        {
            if (Application.Current != null)
            {
                Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    PlayerCards.Add(new TypeModel(t));
                    t.Clear();
                }));
            }
        }

        /// <summary>
        /// 加入到已打牌
        /// </summary>
        /// <param name="t"></param>
        public void CommmencePlayed(TypeModel t)
        {
            if (Application.Current != null)
            {
                Application.Current?.Dispatcher.Invoke((Action)(() =>
                {
                    PlayedCards.Add(new TypeModel(t));
                    t.Clear();
                }));
            }
        }

        #endregion 普通方法

        #region 判定方法

        /// <summary>
        /// 判定吃牌,-1无动作,>=1动作
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int JudgeChow(TypeModel card)
        {
            List<int> orderNumber = new List<int>();
            int totalNumber = 0;
            if (card.Suit == Suit.条 || card.Suit == Suit.饼 || card.Suit == Suit.万)
            {
                for (int i = 0; i < PlayerCards.Count - 1; i++)
                {
                    if (card.Suit == PlayerCards[i].Suit && card.Suit == PlayerCards[i + 1].Suit)
                    {
                        if (card.Rank + 1 == PlayerCards[i].Rank && card.Rank + 2 == PlayerCards[i + 1].Rank)
                        {
                            orderNumber.Add(i);
                            totalNumber++;
                        }
                        else if (card.Rank - 1 == PlayerCards[i].Rank && card.Rank + 1 == PlayerCards[i + 1].Rank)
                        {
                            orderNumber.Add(i);
                            totalNumber++;
                        }
                        else if (card.Rank - 2 == PlayerCards[i].Rank && card.Rank - 1 == PlayerCards[i + 1].Rank)
                        {
                            orderNumber.Add(i);
                            totalNumber++;
                        }
                    }
                }
            }
            else
            {
                totalNumber = -1;
            }
            return totalNumber;
        }

        /// <summary>
        /// 判定碰牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int JudgePung(TypeModel card)
        {
            return 0;
        }

        /// <summary>
        /// 判定杠牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int JudgeKong(TypeModel card)
        {
            return 0;
        }

        /// <summary>
        /// 判定自身和牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int JudgeClaim()
        {
            int PairNum = 0;//将牌数量
            int PungNum;//碰牌数量
            int ChowNum;//吃牌数量
            List<TypeModel> PlayerCardsTemp;

            //判定已明牌数量
            PungNum = OpenedCardsUnKong.Count / 4 + OpenedCardsKong.Count / 4 + OpenedCardsPung.Count / 3;
            ChowNum = OpenedCardsChow.Count / 3;

            //判定手牌各类数量

            //生成临时手牌，排序
            PlayerCardsTemp = new List<TypeModel>(PlayerCards);
            PlayerCardsTemp.Sort(
                (x, y) =>
                {
                    var oSuit = x.Suit - y.Suit;

                    if (oSuit == 0)
                    {
                        if (x.Rank > y.Rank)
                        {
                            return 1;
                        }
                        else if (x.Rank == y.Rank)
                        {
                            return 0;
                        }
                        else
                        {
                            return -1;
                        }
                    }
                    else
                        return Convert.ToInt32(oSuit);
                }
            );
            #region 注释代码
            //手牌+待定为14张牌情况
            //if (PlayerCardsTemp.Count == 14)
            //{
            //    for (int i = 0; i < PlayerCardsTemp.Count - 1; i++)
            //    {
            //        //判断将牌
            //        if (PlayerCardsTemp[i] == PlayerCardsTemp[i + 1])
            //        {
            //            List<TypeModel> t1 = new List<TypeModel>(PlayerCardsTemp);
            //            t1.RemoveAt(i);
            //            t1.RemoveAt(i + 1);//排除奖牌
            //            if (PungInternal(t1))//碰牌数1
            //            {
            //                PungNum++;
            //                if (PungInternal(t1))//碰牌数2
            //                {
            //                    PungNum++;
            //                    if (PungInternal(t1))//碰牌数3
            //                    {
            //                        PungNum++;
            //                        if (PungInternal(t1))//碰牌数4+吃牌数0
            //                        {
            //                            PungNum++;
            //                            return 1;
            //                        }
            //                        else
            //                        {
            //                            if (ChowInternal(t1))//碰牌数3+吃牌数1
            //                            {
            //                                ChowNum++;
            //                                return 1;
            //                            }
            //                            else
            //                            {
            //                                return 0;
            //                            }
            //                        }
            //                    }
            //                    else
            //                    {
            //                        if (ChowInternal(t1))
            //                        {
            //                            ChowNum++;
            //                            if (ChowInternal(t1)) //碰牌数2 + 吃牌数2
            //                            {
            //                                ChowNum++;
            //                                return 1;
            //                            }
            //                            else
            //                            {
            //                                return 0;
            //                            }
            //                        }
            //                        else
            //                        {
            //                            return 0;
            //                        }
            //                    }
            //                }
            //                else
            //                {
            //                    if (ChowInternal(t1))
            //                    {
            //                        ChowNum++;
            //                        if (ChowInternal(t1))
            //                        {
            //                            ChowNum++;
            //                            if (ChowInternal(t1)) //碰牌数1 + 吃牌数3
            //                            {
            //                                ChowNum++;
            //                                return 1;
            //                            }
            //                            else
            //                            {
            //                                return 0;
            //                            }
            //                        }
            //                        else
            //                        {
            //                            return 0;
            //                        }
            //                    }
            //                    else
            //                    {
            //                        return 0;
            //                    }
            //                }
            //            }
            //            else
            //            {
            //                return 0;
            //            }
            //        }
            //        else
            //        {
            //            return 0;
            //        }
            //    }
            //    return 0;
            //}
            //else
            //{
            //    return 0;
            //}
            #endregion

            //2020.06.10



            return 0;




        }

        /// <summary>
        /// 判定其他人打牌和牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int JudgeClaim(TypeModel card)
        {
            int PairNum = 0;//将牌数量
            int PungNum;//碰牌数量
            int ChowNum;//吃牌数量
            List<TypeModel> PlayerCardsTemp;

            //判定已明牌数量
            PungNum = OpenedCardsUnKong.Count / 4 + OpenedCardsKong.Count / 4 + OpenedCardsPung.Count / 3;
            ChowNum = OpenedCardsChow.Count / 3;

            //判定手牌各类数量

            //生成临时手牌，添加待定牌，排序
            PlayerCardsTemp = new List<TypeModel>(PlayerCards);
            PlayerCardsTemp.Add(card);
            PlayerCardsTemp.Sort(
                (x, y) =>
                {
                    var oSuit = x.Suit - y.Suit;

                    if (oSuit == 0)
                    {
                        if (x.Rank > y.Rank)
                        {
                            return 1;
                        }
                        else if (x.Rank == y.Rank)
                        {
                            return 0;
                        }
                        else
                        {
                            return -1;
                        }
                    }
                    else
                        return Convert.ToInt32(oSuit);
                }
            );
            //手牌+待定为14张牌情况
            if (PlayerCardsTemp.Count == 14)
            {
                for (int i = 0; i < PlayerCardsTemp.Count - 1; i++)
                {
                    //判断将牌
                    if (PlayerCardsTemp[i] == PlayerCardsTemp[i + 1])
                    {
                        List<TypeModel> t1 = new List<TypeModel>(PlayerCardsTemp);
                        t1.RemoveAt(i);
                        t1.RemoveAt(i + 1);//排除奖牌
                        if (PungInternal(t1))//碰牌数1
                        {
                            PungNum++;
                            if (PungInternal(t1))//碰牌数2
                            {
                                PungNum++;
                                if (PungInternal(t1))//碰牌数3
                                {
                                    PungNum++;
                                    if (PungInternal(t1))//碰牌数4+吃牌数0
                                    {
                                        PungNum++;
                                        return 1;
                                    }
                                    else
                                    {
                                        if (ChowInternal(t1))//碰牌数3+吃牌数1
                                        {
                                            ChowNum++;
                                            return 1;
                                        }
                                        else
                                        {
                                            return 0;
                                        }
                                    }
                                }
                                else
                                {
                                    if (ChowInternal(t1))
                                    {
                                        ChowNum++;
                                        if (ChowInternal(t1)) //碰牌数2 + 吃牌数2
                                        {
                                            ChowNum++;
                                            return 1;
                                        }
                                        else
                                        {
                                            return 0;
                                        }
                                    }
                                    else
                                    {
                                        return 0;
                                    }
                                }
                            }
                            else
                            {
                                if (ChowInternal(t1))
                                {
                                    ChowNum++;
                                    if (ChowInternal(t1))
                                    {
                                        ChowNum++;
                                        if (ChowInternal(t1)) //碰牌数1 + 吃牌数3
                                        {
                                            ChowNum++;
                                            return 1;
                                        }
                                        else
                                        {
                                            return 0;
                                        }
                                    }
                                    else
                                    {
                                        return 0;
                                    }
                                }
                                else
                                {
                                    return 0;
                                }
                            }
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    else
                    {
                        return 0;
                    }
                }
                return 0;
            }
            else
            {
                return 0;
            }

        }

        #endregion 判定方法

        #region 动作方法

        /// <summary>
        /// 和牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int Claim(TypeModel card)
        {
            return 0;
        }

        /// <summary>
        /// 杠牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int Kong(TypeModel card)
        {
            return 0;
        }

        /// <summary>
        /// 碰牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int Pung(TypeModel card)
        {
            return 0;
        }

        /// <summary>
        /// 吃牌
        /// </summary>
        /// <param name="card"></param>
        /// <returns></returns>
        public int Chow(TypeModel card)
        {
            return 0;
        }

        #endregion 动作方法

        #region 内部方法

        private bool PungInternal(List<TypeModel> t)
        {
            t.Sort(
                (x, y) =>
                {
                    var oSuit = x.Suit - y.Suit;

                    if (oSuit == 0)
                    {
                        if (x.Rank > y.Rank)
                        {
                            return 1;
                        }
                        else if (x.Rank == y.Rank)
                        {
                            return 0;
                        }
                        else
                        {
                            return -1;
                        }
                    }
                    else
                        return Convert.ToInt32(oSuit);
                }
            );
            for (int i = 0; i < t.Count - 2; i++)
            {
                if (t[i] == t[i + 1] && t[i] == t[i + 2])
                {
                    t.RemoveAt(i);
                    t.RemoveAt(i + 1);
                    t.RemoveAt(i + 2);
                    return true;
                }
            }
            return false;
        }

        private bool ChowInternal(List<TypeModel> t)
        {
            t.Sort(
                (x, y) =>
                {
                    var oSuit = x.Suit - y.Suit;

                    if (oSuit == 0)
                    {
                        if (x.Rank > y.Rank)
                        {
                            return 1;
                        }
                        else if (x.Rank == y.Rank)
                        {
                            return 0;
                        }
                        else
                        {
                            return -1;
                        }
                    }
                    else
                        return Convert.ToInt32(oSuit);
                }
            );
            for (int i = 0; i < t.Count - 1; i++)
            {
                TypeModel t1 = new TypeModel(t[i]);
                List<TypeModel> t2 = new List<TypeModel>(t);
                t2.RemoveAt(i); //将待判断牌取出

                if (t1.Suit == Suit.条 || t1.Suit == Suit.饼 || t1.Suit == Suit.万)
                {
                    for (int j = 0; j < t2.Count - 1; j++)
                    {
                        if (t1.Suit == t2[j].Suit && t1.Suit == t2[j + 1].Suit)
                        {
                            if (t1.Rank + 1 == t2[j].Rank && t1.Rank + 2 == t2[j + 1].Rank)
                            {
                                t.RemoveAt(i);
                                t.RemoveAt(j + 1);
                                t.RemoveAt(j + 2);
                                return true;
                            }
                            else if (t1.Rank - 1 == t2[j].Rank && t1.Rank + 1 == t2[j + 1].Rank)
                            {
                                t.RemoveAt(i);
                                t.RemoveAt(j + 1);
                                t.RemoveAt(j + 2);
                                return true;
                            }
                            else if (t1.Rank - 2 == t2[j].Rank && t1.Rank - 1 == t2[j + 1].Rank)
                            {
                                t.RemoveAt(i);
                                t.RemoveAt(j + 1);
                                t.RemoveAt(j + 2);
                                return true;
                            }
                        }
                    }
                }
                else
                {
                    return false;
                }
            }
            return false;
        }

        #endregion 内部方法
    }
}